In [1]:
%matplotlib nbagg
%pylab
In [142]:
import main
raw_data = main.load_raw_data([]) # asume el cache
gdf = main.get_grouped_dataset(raw_data, level=4)
m, dfX = main.get_model_to_draw(4)
El análisis que presento sucintamente acá se basa en la hipótesis que la distribución de votos en una mesa electoral permite describir a la población que votó allí.
De esa forma podemos buscar patrones que ocurran a lo largo de todas las mesas electorales.
Lo más sencillo es empezar por mirar la distribución conjunta, respondiendo a esta pregunta:
In [143]:
import model
figure()
distr = model.ConditionalDistribution(gdf['131_pct'], gdf['135_pct']).fit()
distr.draw_joint()
xlabel('Proporción de votos a Scioli'.decode('utf8'))
ylabel('Proporción de votos a Macri'.decode('utf8'))
Out[143]:
Hay una relación inversa entre la gente que votó a Macri y a Scioli. Eso ya lo sabemos. Otra cósa interesante que se puede ver, es que la zona más roja del gráfico corresponde aproximadamente al resultado final que obtuvieron los candidatos.
In [144]:
figure()
distr = model.ConditionalDistribution(gdf['138_pct'], gdf['131_pct']).fit()
distr.draw_joint()
xlabel('Proporción de votos a Massa'.decode('utf8'))
ylabel('Proporción de votos a Scioli'.decode('utf8'))
Out[144]:
Este patrón es super interesante, parecería haber dos secciones, una donde Massa tiene al rededor de 15%, y luego una cola, donde Massa tiene mayor cantidad de votos, y esa mayor cantidad de votos correlaciona con la cantidad de votos a Scioli.
In [145]:
figure()
distr = model.ConditionalDistribution(gdf['138_pct'], gdf['135_pct']).fit()
distr.draw_joint()
xlabel('Proporción de votos a Massa'.decode('utf8'))
ylabel('Proporción de votos a Macri'.decode('utf8'))
Out[145]:
Este es otro patrón muy interesante, tiene claramente una correlación negativa: A mayor cantidad de votos a Massa, menor a Macri.
Dicho mal y pronto, la idea es utilizar la información que se encuentra en estas distribuciones para estimar como se repartirían los votos, de forma tal que se respeten los patrones que observamos.
El proceso lo ejecuté agrupando en distintas granularidades. Como el proceso es lento, solo presento los resultados agrupando por Provincia y Departamento.
In [146]:
level = 4
raw_data = main.load_raw_data([]) # asume el cache
gdf = main.get_grouped_dataset(raw_data, level=level)
totals = {}
for k in u'131', u'132', u'133', u'135', u'137', u'138':
totals[k] = gdf[k].sum()
s = sum(totals.values())
# Como el proceso es lento, en lugar de ejecutarlo en este notebook,
# se ejecuta en un proceso que guarda los resultados en una collection de mongodb
import main
# row_id = max(main.save_collection.find({'predict_level': level}).distinct('row_id'))
# docs = list(main.save_collection.find({'predict_level': level, 'row_id': row_id}))
row_id = max(main.save_collection.find({'level': level}).distinct('row_id'))
docs = list(main.save_collection.find({'level': level, 'row_id': row_id}))
print len(docs)
In [147]:
import pandas as pd
df = pd.DataFrame([e['pred'] for e in docs])
df['131_pct'] += totals['131']
df['135_pct'] += totals['135']
s = df['135_pct'] + df['131_pct']
df['131_pct_pct'] = df['131_pct'] / s
df['135_pct_pct'] = df['135_pct'] / s
In [148]:
figure()
(df['131_pct_pct']).hist(alpha=0.65, color='b')
(df['135_pct_pct']).hist(alpha=0.65, color='y')
legend(('Scioli', 'Macri'))
Out[148]:
Este resultado es bastante sorprendente. Hay dos posibles interpretaciones
El resultado que según este modelo va a ocurrir con 95% de probabilidad
In [149]:
print np.percentile(df['131_pct_pct'], [.5, 99.5])
print np.percentile(df['135_pct_pct'], [.5, 99.5])